package com.laguille.games.monopoly.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.Validate;

import com.laguille.games.monopoly.commons.board.Board;
import com.laguille.games.monopoly.commons.player.Player;
import com.laguille.games.monopoly.commons.property.Property;

public class GameContextImpl implements GameContext {

	private Board board;
	private final List<Player> allPlayers;
	private List<Player> activePlayers;
	private Player currentPlayer;

	public GameContextImpl(Board board) {
		Validate.notNull(board);

		this.board = board;
		this.allPlayers = new ArrayList<Player>(10);
		this.activePlayers = new ArrayList<Player>(10);
	}

	@Override
	public Board getBoard() {
		return board;
	}

	@Override
	public void registerPlayer(Player player) {
		Validate.notNull(player);
		Validate.isTrue(!allPlayers.contains(player));
		Validate.isTrue(!activePlayers.contains(player));
		
		allPlayers.add(player);
		activePlayers.add(player);
		
		if (this.currentPlayer == null) {
			this.currentPlayer = player;
		}
	};
	
	@Override
	public List<Player> getPlayers() {
		return Collections.unmodifiableList(activePlayers);
	}

	@Override
	public List<Player> getAllPlayers() {
		return Collections.unmodifiableList(allPlayers);
	}
	
	@Override
	public void removePlayerFromGame(Player player) {
		Validate.notNull(player);
		Validate.isTrue(activePlayers.contains(player));
		Validate.isTrue(activePlayers.size() > 1);
		
		activePlayers.remove(player);
		
	}

	@Override
	public Player getCurrentPlayer() {
		return currentPlayer;
	}

	@Override
	public void nextPlayer() {
		int currentPlayerIdx = activePlayers.indexOf(currentPlayer);
		currentPlayer = activePlayers.get(currentPlayerIdx + 1 % activePlayers.size());
	}
	
	@Override
	public boolean isGameOver() {
		return activePlayers.size() == 1;
	}

	@Override
	public Player getWinner() {
		return isGameOver() ? activePlayers.get(0) : null;
	}

	@Override
	public Player getOwner(Property property) {
		Validate.notNull(property);

		for (Player player : activePlayers) {
			if (player.getPropertySet().contains(property)) {
				return player;
			}
		}
		
		return null;
	}

}
